
package com.fish.service.impl.passport;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.fish.order.po.Order;
import com.fish.passport.dao.PassCodeDAO;
import com.fish.passport.dao.PassEventDAO;
import com.fish.passport.dao.PassPortCodeDAO;
import com.fish.passport.dao.PassProviderDAO;
import com.fish.passport.po.PassCode;
import com.fish.passport.po.PassEvent;
import com.fish.passport.po.PassPortCode;
import com.fish.passport.po.PassProvider;
import com.fish.product.po.PerformTarget;
import com.fish.service.passport.MakePassCodeService;
import com.fish.utils.DateUtil;
import com.fish.utils.UUIDGenerator;
import com.fish.vo.PassportConstant;

/**
 * 通关系统请求适配器
 * 
 * @author chenlinjun
 * 
 */
public class MakePassCodeServiceImpl implements MakePassCodeService {
	private static final Log log = LogFactory.getLog(MakePassCodeServiceImpl.class);
	private static final String ORDER_ITEM = "ORD_ORDER_ITEM_META";
	private static final String ORDER = "ORD_ORDER";
	private PassEventDAO passEventDAO;
	private PassPortCodeDAO passPortCodeDAO;
	private PassCodeDAO passCodeDAO;
	private PassProviderDAO passProviderDAO;

	public PassCode getPassCodeByCodeId(String codeId) {
		return passCodeDAO.getPassCodeByCodeId(codeId);
	}
	/**
	 * 废码
	 */
	public PassEvent destroyCode(String codeId) {
		PassCode passCode = passCodeDAO.getPassCodeByCodeId(codeId);
		PassEvent event = new PassEvent();
		event.setEventId(UUIDGenerator.getNewUUID());
		event.setCodeId(passCode.getCodeId());
		event.setType(PassportConstant.PASSCODE_TYPE.DESTROYCODE.name());
		event.setStatus(PassportConstant.PASSCODE_HANDL_STATUS.NOHANDL.name());
		//TODO 以后扩展对通关点废码处理时需要此参数
		//event.setOutPortId(Long.valueOf(this.passport.getOutPortId()));
		event.setApplyTime(new Date());
		passEventDAO.addEvent(event);
		return event;
	}
	/**
	 * 订单申请码
	 */
	public List<PassCode> applyCodeForOrder(Order order,Map<Long,List<PerformTarget>> performTargetMap) {
		Long orderId=order.getOrderId();
		Set<PassProvider> providerSet = new HashSet<PassProvider>();
		List<PerformTarget> perfromList=performTargetMap.get(orderId);
		for(PerformTarget perfromTarget:perfromList){
			PassProvider provider = passProviderDAO.selectByPerformTargetId(perfromTarget.getTargetId());
			if (provider!=null) {
				providerSet.add(provider);
			}
		}
		List<PassCode> passCodeList = new ArrayList<PassCode>();
		int codeTotal=0;//要申请码的数量
		for (PassProvider passProvider : providerSet) {
			if (passProvider.isSeparatelyApply()) {	//服务商对每个订单子子项独立申码
					codeTotal=codeTotal+1;
					for(PerformTarget perfromTarget:perfromList) {
						PassCode code = apply(order.getContactPhone(), orderId,orderId, ORDER_ITEM);
						String terminalContent = mergePrintContent(order);
						initPassPortCode(code, perfromTarget.getTargetId(), order.getVisitTime(), order.getVisitEndTime(), terminalContent);
						if(passProvider.isSendSmsByProvider()){
							this.mergeSms(code, order);
						}
						passCodeList.add(code);
					}
					
			}else{//合并申码
				codeTotal=codeTotal+1;
				PassCode code = apply(order.getContactPhone(), orderId,orderId, ORDER);
				Set<String>perfomTargetSet=new HashSet<String>();
				for(PerformTarget perfromTarget:perfromList){
					perfomTargetSet.add(perfromTarget.getTargetId());
				}
				for (String targetId : perfomTargetSet) {
					String terminalContent = mergePrintContent(order);
					initPassPortCode(code, targetId, order.getVisitTime(), order.getVisitEndTime(), terminalContent);
				}
				if(passProvider.isSendSmsByProvider()){
					this.mergeSms(code, order);
				}
				passCodeList.add(code);
			}
		}
		//设置订单申请码的个数
		this.passCodeDAO.updateCodeTotalByOrder(order.getOrderId(), codeTotal);
		return passCodeList;
	}
	
	private void initPassPortCode(PassCode passCode, String targetId, Date visitTime, Date visitEndTime, String terminalContent) {
		PassPortCode passPortCode = new PassPortCode();
		passPortCode.setPassportCodeId(UUIDGenerator.getNewUUID());
		passPortCode.setTargetId(targetId);
		passPortCode.setStatus(PassportConstant.PASSCODE_USE_STATUS.UNUSED.name());
		passPortCode.setCodeId(passCode.getCodeId());
		passPortCode.setValidTime(visitTime);
		passPortCode.setInvalidTime(visitEndTime);
		passPortCode.setTerminalContent(terminalContent);
		// 添加通关码关联信息
		passPortCodeDAO.addPassPortCode(passPortCode);
	}
	/**
	 * 组合短信
	 * @return
	 */
	private void mergeSms(PassCode passCode,Order order){
		//${addCode} ${code} ${orderId} 游玩时间：${visitDate},有效期：${time},${quantityContent}。${content}，将此短信交景区验证。本凭证验证后即失效，切勿转发，多人请一起入园。如需帮助请致电驴妈妈旅游网客服中心10106060(免长话费）。
		String smsContent = this.passCodeDAO.selectTemplateByCode("SMS").getTemplateContent();
		String visitDate = DateUtil.getFormatDate(order.getVisitTime(), "yyyy-MM-dd");
		String visitEndDate = DateUtil.getFormatDate(order.getVisitEndTime(), "yyyy-MM-dd");
		
		smsContent = StringUtils.replace(smsContent, "${orderId}", "订单号:"+order.getOrderId().toString());
		smsContent = StringUtils.replace(smsContent, "${visitDate}", visitDate);
		smsContent = StringUtils.replace(smsContent, "${addCode}", passCode.getAddCode());
		smsContent = StringUtils.replace(smsContent, "${code}", passCode.getCode());
		smsContent = StringUtils.replace(smsContent, "${quantityContent}", String.valueOf(order.getQuantity()));
		smsContent = StringUtils.replace(smsContent, "${time}", visitEndDate);
		String content=order.getSmsContent();
		smsContent = StringUtils.replace(smsContent, "${content}", content);
		
		log.info("Passport SmsContent:"+smsContent);
		
		PassCode temp=new PassCode();
		temp.setCodeId(passCode.getCodeId());
		temp.setSmsContent(smsContent);
		passCodeDAO.updatePassCode(temp);
		
	}

	
	/**
	 * 显示内容
	 * 
	 * @param person
	 * @param itemMeta
	 * @param itemProd
	 * @return
	 */
	public String mergePrintContent(Order order) {
		/**
		 
		订单:${orderId}
		产品名称:${productName}
		份数：${Quantity}份
		单价:${price}元
		订单金额:${OrderPrice}元
		订票人:${clientName}(${clientMobile})
		 */

		String content =  this.passCodeDAO.selectTemplateByCode("PRINT").getTemplateContent();
		StringBuilder productNameBuf = new StringBuilder();
		String productName=order.getProductName();
			int len = productName.length();
			if (len > 11) {
				productName = productName.substring(0, 11) + "\n" + productName.substring(11);
			}
		productNameBuf.append(productName + ",");
		content = StringUtils.replace(content, "${orderId}", order.getOrderId().toString());
		content = StringUtils.replace(content, "${productName}", productNameBuf.toString());
		content = StringUtils.replace(content, "${price}", String.valueOf(order.getSellPrice()));
		content = StringUtils.replace(content, "${Quantity}", "" + order.getQuantity());
		if(!order.isPayToFish()){
			content = StringUtils.replace(content, "${OrderPrice}", "" + order.getOrderPrice());
		}else{
			content = StringUtils.replace(content, "${OrderPrice}", "--" );
		}
		content = StringUtils.replace(content, "${clientName}", order.getContactName());
		content = StringUtils.replace(content, "${clientMobile}", order.getContactPhone());
		log.info("mergePrintContent info:"+content);
		return content;
	}
		
	private PassCode apply(String mobile,Long orderId, Long objectId, String objectType) {
		String serialNo = DateUtil.getFormatDate(new Date(), "yyyyMMddHHmmss") ;
		// 通关码
		PassCode passCode = new PassCode();
		passCode.setCodeId(UUIDGenerator.getNewUUID());
		passCode.setCreateTime(new Date());
		passCode.setObjectId(objectId);
		passCode.setObjectType(objectType);
		passCode.setReapply(PassportConstant.PASSCODE_REAPPLY_STATUS.FALSE.name());
		passCode.setMobile(mobile);
		passCode.setOrderId(orderId);
		passCode.setSerialNo(serialNo);
		passCode.setStatus(PassportConstant.PASSCODE_HANDL_STATUS.NOHANDL.name());
		passCode.setReapplyCount(0l);
		this.passCodeDAO.addPassCode(passCode);
		return passCode;
	}
	
	public String reApplyCode(String codeId) {
		PassCode passCode = passCodeDAO.getPassCodeByCodeId(codeId);
		passCode.setReapply(PassportConstant.PASSCODE_REAPPLY_STATUS.TRUE.name());
		passCode.setStatusExplanation("");
		passCodeDAO.updatePassCode(passCode);
		
		String serialNo = DateUtil.getFormatDate(new Date(), "yyyyMMddHHmmss");
		String newCodeId=UUIDGenerator.getNewUUID();
		passCode.setSerialNo(serialNo);
		passCode.setCodeId(newCodeId);
		passCode.setStatus("NOHANDL");
		passCode.setCreateTime(new Date());
		passCode.setUpdateTime(new Date());
		passCode.setStatusNo(null);
		passCode.setStatusExplanation(null);
		passCode.setReapplyCount(passCode.getReapplyCount()+1);
		passCode.setCodeTotal(passCode.getCodeTotal());
		passCodeDAO.addPassCode(passCode);
		List<PassPortCode> list = passPortCodeDAO.queryPassPortCodes(codeId);
		for (PassPortCode passPortCode : list) {
			passPortCode.setPassportCodeId(UUIDGenerator.getNewUUID());
			passPortCode.setCodeId(newCodeId);
			passPortCodeDAO.addPassPortCode(passPortCode);
		}
		return newCodeId;
	}
	
	/**
	 * 废码处理
	 * 
	 * @param orderId
	 */
	public List<PassEvent> destroyCode(Order order) {
		List<PassCode> list = passCodeDAO.getPassCodeByOrderId(order.getOrderId());
		List<PassEvent> eventList = new ArrayList<PassEvent>();
		for (PassCode passCode : list) {
			PassEvent event = new PassEvent();
			event.setEventId(UUIDGenerator.getNewUUID());
			event.setCodeId(passCode.getCodeId());
			event.setType(PassportConstant.PASSCODE_TYPE.DESTROYCODE.name());
			event.setStatus(PassportConstant.PASSCODE_HANDL_STATUS.NOHANDL.name());
			//TODO 以后扩展对通关点废码处理时需要此参数
			//event.setOutPortId(Long.valueOf(this.passport.getOutPortId()));
			event.setApplyTime(new Date());
			passEventDAO.addEvent(event);
			eventList.add(event);
		}
		return eventList;
	}

	/**
	 * 更新订单联系人
	 */
	public List<PassEvent> updateContact(Order order) {
		List<PassCode> list = passCodeDAO.getPassCodeByOrderId(order.getOrderId());
		List<PassEvent> eventList = new ArrayList<PassEvent>();
		for (PassCode passCode : list) {
			PassEvent event = new PassEvent();
			event.setEventId(UUIDGenerator.getNewUUID());
			event.setCodeId(passCode.getCodeId());
			event.setType(PassportConstant.PASSCODE_TYPE.UPDATECONTACT.name());
			event.setStatus(PassportConstant.PASSCODE_HANDL_STATUS.NOHANDL.name());
			event.setTerminalContent(order.getCertNo());
			event.setApplyTime(new Date());
			passEventDAO.addEvent(event);
			eventList.add(event);
		}
		return eventList;
	}
	/**
	 * 重发短信
	 * @param order
	 * @return
	 */
	public List<PassEvent> resend(Order order){
		List<PassCode> list = passCodeDAO.getPassCodeByOrderId(order.getOrderId());
		List<PassEvent> eventList = new ArrayList<PassEvent>();
		for (PassCode passCode : list) {
			PassEvent event = new PassEvent();
			event.setEventId(UUIDGenerator.getNewUUID());
			event.setCodeId(passCode.getCodeId());
			event.setType(PassportConstant.PASSCODE_TYPE.RESEND.name());
			event.setStatus(PassportConstant.PASSCODE_HANDL_STATUS.NOHANDL.name());
			event.setApplyTime(new Date());
			passEventDAO.addEvent(event);
			eventList.add(event);
		}
		return eventList;
	}
	/**
	 * 重发短信
	 * @param codeId
	 * @return
	 */
	public PassEvent resend(String codeId) {
		PassCode passCode = passCodeDAO.getPassCodeByCodeId(codeId);
		PassEvent event = new PassEvent();
		event.setEventId(UUIDGenerator.getNewUUID());
		event.setCodeId(passCode.getCodeId());
		event.setType(PassportConstant.PASSCODE_TYPE.RESEND.name());
		event.setStatus(PassportConstant.PASSCODE_HANDL_STATUS.NOHANDL.name());
		event.setApplyTime(new Date());
		passEventDAO.addEvent(event);
		return event;
	}
	
	/**
	 * 通过时间查询重新申请码记录
	 * @param params
	 * @return
	 */
	public List<PassCode> selectByReapplyTime() {
		return this.passCodeDAO.selectByReapplyTime();
	}
	public List<PassEvent> updateContent(Order order) {
		return null;
	}

	public List<PassEvent> updatePerson(Order order) {
		return null;
	}

	/**
	 * 查询已经支付了但是没有收到支付消息的订单
	 * @return
	 */
	public List<Object> selectReapplyOrder(){
		return this.passCodeDAO.selectReapplyOrder();
	}
	
	/**
	 * 判断订单或订单子指项是否已经申请成功过码
	 * @param params
	 * @return
	 */
	public boolean hasSuccessCode(String orderId,long codeTotal ){
		Map<String,Object> params=new HashMap<String,Object>();
		params.put("orderId",orderId);
		int successCodeNum=passCodeDAO.successCodeNum(params);
		if(successCodeNum>=codeTotal){
			return true;
		}else{
			return false;
		}
	}
	/**
	 * 订单是否已经做过申请
	 * @param orderId
	 * @return
	 */
	public boolean hasApply(String orderId){
		Map<String,Object> params=new HashMap<String,Object>();
		params.put("orderId", orderId);
		List<PassCode> passCodeList = passCodeDAO.selectPassCodeByParams(params);
		if(passCodeList!=null&&passCodeList.size()>0){
			return true;
		}else{
		    return false;
		}
	}
	public void setPassEventDAO(PassEventDAO passEventDAO) {
		this.passEventDAO = passEventDAO;
	}

	public void setPassPortCodeDAO(PassPortCodeDAO passPortCodeDAO) {
		this.passPortCodeDAO = passPortCodeDAO;
	}

	public void setPassCodeDAO(PassCodeDAO passCodeDAO) {
		this.passCodeDAO = passCodeDAO;
	}
 
	public void setPassProviderDAO(PassProviderDAO passProviderDAO) {
		this.passProviderDAO = passProviderDAO;
	}

}
